package msecurity.cliente;

import java.io.*;
import java.net.*;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;


public class Cliente {
        public Cliente(){}
        
        public static void startClient() throws IOException{
                Socket server     = null;
                BufferedReader in = null;
                try{
                        server = new Socket("192.168.0.137",5050);
                        in     = new BufferedReader(new InputStreamReader(server.getInputStream()));
                }catch(Exception e){
                        System.out.println(e.getMessage());
                        System.exit(-1);
                }
                //DataInputStream di = new DataInputStream(server.getInputStream());
                try{
                        byte[] data = Recibir(server);
                        FileOutputStream fs = new FileOutputStream(new File(".").getCanonicalPath()+"/xml/recibido.xml");
                        fs.write(data);
                        fs.close();
                        //obtener el id de cliente dese el mensaje de bienvenida recibido
                        Mensaje mensaje = new Mensaje();
                        mensaje.Deserialize(new File(new File(".").getCanonicalPath()+"/xml/recibido.xml"));
                        System.out.println("Mi id es : "+mensaje.getID());
                        //enviar un mensaje LIST 
                        mensaje.setTipo(Mensaje.MsgType.LIST);
                        mensaje.setContenido("Listado de Videos");
                        //se envia la solicitud de listado
                        SendMsg(server,mensaje);
                        System.out.println("Solicitud de Listado enviada");
                        System.out.println("Recibiendo...");
                        data = Recibir(server);
                        fs = new FileOutputStream(new File(".").getCanonicalPath()+"/xml/listado.xml");
                        fs.write(data);
                        fs.close();
                        System.out.println("Listado recibido... Mostrando...");
                        File file = new File(new File(".").getCanonicalPath()+"/xml/listado.xml");
                    	List<VideoList> listado = VideoList.Deserialize(file);
                		Iterator<VideoList> it = listado.iterator();
                		while(it.hasNext()){
                			VideoList v = (VideoList)it.next();
                			System.out.println("Titulo "+v.getTitulo());
                			System.out.println("\tID: "+v.getId()+" | Path: "+v.getPath());
                		}
                		
                        server.close();
                }catch(Exception e){
                        e.printStackTrace();
                }
                
                
                in.close();
                server.close();
        }
        
        private static byte[] ReadFully (FileInputStream stream) throws IOException{
                int initialLength = 1024;
                byte[] buffer = new byte[initialLength];
                int read=0;
                int chunk;
                while ( (chunk = stream.read(buffer, read, buffer.length-read)) > 0){
                read += chunk;
                        if (read == buffer.length){
                        int nextByte = stream.read();
                    if (nextByte==-1){
                        return buffer;
                        }
                byte[] newBuffer = new byte[buffer.length*2];
                        System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
                        newBuffer[read]=(byte)nextByte;
                        buffer = newBuffer;
                        read++;
                }
                }
                byte[] ret = new byte[read];
                System.arraycopy(buffer, 0, ret, 0, read);
                return ret;
        }
        
        
        private static void SendMsg(Socket socket, Mensaje mensaje) throws IOException, ParserConfigurationException, TransformerException{
                String archivo = mensaje.Serialize();
                
                FileInputStream fs = new FileInputStream(new File(archivo));
                byte[] fileToSend = ReadFully(fs);
                fs.close();
                //Send size
                OutputStream os = socket.getOutputStream();
                os.write(intToByteArray(fileToSend.length));
                os.flush();
                
                os.write(fileToSend,0,fileToSend.length);
                os.flush();
                
        }
        
        
        
        private static byte[] Recibir(Socket server) throws IOException{
                int total = 0;
                int recv;
                DataInputStream di = new DataInputStream(server.getInputStream());
                byte[] datasize = new byte[4];
                recv = di.read(datasize,0,4);
                int size = byteArrayToInt(datasize);
                int dataleft = size;
                di = new DataInputStream(server.getInputStream());
                byte[] data = new byte[size];
                while(total < size){
                        recv = di.read(data,total,dataleft);
                        if(recv == -1 || recv == 0){
                                break;
                        }
                        total += recv;
                        dataleft-=recv;
                }
                
                return data;
        }
        
        /**
     * Convert the byte array to an int.
     *
     * @param b The byte array
     * @return The integer
     */
    private static int byteArrayToInt(byte[] b) {
        return byteArrayToInt(b, 0);
    }

    /**
     * Convert the byte array to an int starting from the given offset.
     *
     * @param b The byte array
     * @param offset The array offset
     * @return The integer
     */
    private static int byteArrayToInt(byte[] b, int offset) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (b[i + offset] & 0x000000FF) << shift;
        }
        return value;
    }
    
    private static byte[] intToByteArray(int value) {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            int offset = (b.length - 1 - i) * 8;
            b[i] = (byte) ((value >>> offset) & 0xFF);
        }
        return b;
    }
        
        public static void main(String args[]){
                try{
                    Cliente.startClient();
                	
                }catch(Exception e){
                        e.printStackTrace();
                }
        }
        
        
}


